package com.ruoyi.web.controller.wechatlogin;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.*;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

/**
 * http post 请求实体类
 * @author lmg
 * @date 2019年7月9日
 *
 */
public class HttpsRequest {
	public enum RequetType{
		//json请求
		JSON(0),

		//表单请求
		FORM(1);

		private int value;

		RequetType(int value) {
			this.value = value;
		}

		public int getValue() {
			return value;
		}
	}

	private static Logger logger = LoggerFactory.getLogger(HttpsRequest.class);

	/**
	 * @description post请求方法
	 * @param params: 请求参数
	 * @param headers: 请求头
	 * @param formType: 请求类型 json /form
	 * @return null
	 * @author lmg
	 * @date 2023-12-22 14:24
	 * @version v1.01
	 */
	public String doPost(String url,Map<String, Object> params,Map<String, String> headers,RequetType formType) throws Exception {
		String parameterData = JSON.toJSONString(params,SerializerFeature.WriteMapNullValue);
		logger.error("*****https发送的数据为:\t" + parameterData);

		trustAllHosts();
		URL localURL = new URL(url);
		URLConnection connection = localURL.openConnection();
		HttpsURLConnection httpsURLConnection = (HttpsURLConnection)connection;
		httpsURLConnection.setHostnameVerifier(DO_NOT_VERIFY);

		httpsURLConnection.setDoOutput(true);
		httpsURLConnection.setDoInput(true);
		httpsURLConnection.setRequestMethod("POST");
		// 设置通用的请求属性
		httpsURLConnection.setRequestProperty("accept", "*/*");
		httpsURLConnection.setRequestProperty("Accept-Charset", "utf-8");
		if(formType.getValue()== RequetType.JSON.getValue()){
			httpsURLConnection.setRequestProperty("Content-Type",  "application/json;charset=UTF-8");
		}else if(formType.getValue()== RequetType.FORM.getValue()){
			httpsURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
		}else{

		}
		httpsURLConnection.setRequestProperty("Content-Length", String.valueOf(parameterData.length()));
		if(headers!=null){
			for (String key: headers.keySet()){
				httpsURLConnection.setRequestProperty(key, headers.get(key));
			}
		}
		httpsURLConnection.setConnectTimeout(5*1000);//设置超时时间
		httpsURLConnection.setReadTimeout(5*1000);

		OutputStream outputStream = null;
		OutputStreamWriter outputStreamWriter = null;
		InputStream inputStream = null;
		InputStreamReader inputStreamReader = null;
		BufferedReader reader = null;
		StringBuffer resultBuffer = new StringBuffer();
		String tempLine = null;

		try {
			outputStream = httpsURLConnection.getOutputStream();
			outputStreamWriter = new OutputStreamWriter(outputStream);
			if(formType.getValue()== RequetType.JSON.getValue()){
				outputStreamWriter.write(parameterData.toString());
			}else if(formType.getValue()== RequetType.FORM.getValue()){
				outputStreamWriter.write(paramsConvert(params));
			}else{

			}
			outputStreamWriter.flush();
			if (httpsURLConnection.getResponseCode() >= 300) {
				throw new Exception("HTTP Request is not success, Response code is " + httpsURLConnection.getResponseCode());
			}
			inputStream = httpsURLConnection.getInputStream();
			inputStreamReader = new InputStreamReader(inputStream,"UTF-8");
			reader = new BufferedReader(inputStreamReader);
			while ((tempLine = reader.readLine()) != null) {
				resultBuffer.append(tempLine);
			}
		} finally {
			if (outputStreamWriter != null) {
				outputStreamWriter.close();
			}
			if (outputStream != null) {
				outputStream.close();
			}
			if (reader != null) {
				reader.close();
			}
			if (inputStreamReader != null) {
				inputStreamReader.close();
			}

			if (inputStream != null) {
				inputStream.close();
			}
		}
		logger.error("*****https接受的数据为:\t" + resultBuffer.toString());
		return resultBuffer.toString();
	}


	/**
	 * 参数类型转换
	 *
	 * @param parameters
	 * @return
	 * @throws Exception
	 */
	public static String paramsConvert(Map<String, Object> parameters) throws Exception {
		StringBuffer sb = new StringBuffer();// 处理请求参数
		// 编码请求参数
		for (String name : parameters.keySet()) {
			Object object = parameters.get(name);
			if(object instanceof Integer) {
				sb.append(name).append("=").append(java.net.URLEncoder.encode((String)object, "UTF-8"))
						.append("&");
			}else if(object instanceof Date) {
				Calendar cal = Calendar.getInstance();
				cal.setTime((Date)object);
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				sb.append(name).append("=").append(java.net.URLEncoder.encode(sdf.format(cal.getTime()), "UTF-8"))
						.append("&");
			}else{
				if(object.getClass().isArray()) {//判断是否是字符串数组
					String[] values = (String[])object;
					for(String va : values) {
						sb.append(name).append("=").append(java.net.URLEncoder.encode((String) va, "UTF-8"))
								.append("&");
					}
				}else {
					sb.append(name).append("=").append(java.net.URLEncoder.encode((String) parameters.get(name), "UTF-8"))
							.append("&");
				}
			}
		}
		return sb.toString().substring(0, sb.toString().length()-1);
	}



	public static void main(String[] args) throws Exception {
		HttpsRequest request = new HttpsRequest();
		String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=wx8e49190d5738a9b3&secret=81c51ec9b34284790eaf197a9ed8511d&code=0e3wHg000BtWaR1brC000UIi4w3wHg0N&grant_type=authorization_code";
		String s = request.doGet(url);
		System.out.println(s);
	}

	public String doGet(String url) throws Exception {
		trustAllHosts();
		URL localURL = new URL(url);
		URLConnection connection = localURL.openConnection();
		HttpsURLConnection httpsURLConnection = (HttpsURLConnection)connection;
		httpsURLConnection.setHostnameVerifier(DO_NOT_VERIFY);

		httpsURLConnection.setDoOutput(true);
		httpsURLConnection.setDoInput(true);
		httpsURLConnection.setRequestMethod("GET");
		// 设置通用的请求属性
		httpsURLConnection.setRequestProperty("accept", "*/*");
		httpsURLConnection.setRequestProperty("Accept-Charset", "utf-8");
		//httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
		httpsURLConnection.setRequestProperty("Content-Type",  "application/json;charset=UTF-8");
		httpsURLConnection.setConnectTimeout(5*1000);//设置超时时间
		httpsURLConnection.setReadTimeout(5*1000);

		OutputStream outputStream = null;
		OutputStreamWriter outputStreamWriter = null;
		InputStream inputStream = null;
		InputStreamReader inputStreamReader = null;
		BufferedReader reader = null;
		StringBuffer resultBuffer = new StringBuffer();
		String tempLine = null;

		try {
			outputStream = httpsURLConnection.getOutputStream();
			outputStreamWriter = new OutputStreamWriter(outputStream);
			outputStreamWriter.flush();
			if (httpsURLConnection.getResponseCode() >= 300) {
				throw new Exception("HTTP Request is not success, Response code is " + httpsURLConnection.getResponseCode());
			}
			inputStream = httpsURLConnection.getInputStream();
			inputStreamReader = new InputStreamReader(inputStream,"UTF-8");
			reader = new BufferedReader(inputStreamReader);
			while ((tempLine = reader.readLine()) != null) {
				resultBuffer.append(tempLine);
			}
		} finally {
			if (outputStreamWriter != null) {
				outputStreamWriter.close();
			}
			if (outputStream != null) {
				outputStream.close();
			}
			if (reader != null) {
				reader.close();
			}
			if (inputStreamReader != null) {
				inputStreamReader.close();
			}

			if (inputStream != null) {
				inputStream.close();
			}
		}
		logger.error("*****https接受的数据为:\t" + resultBuffer.toString());
		return resultBuffer.toString();
	}


	private final HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
		@Override
		public boolean verify(String hostname, SSLSession session) {
			return true;
		}
	};

	private void trustAllHosts() {
		// Create a trust manager that does not validate certificate chains
		TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
			@Override
			public X509Certificate[] getAcceptedIssuers() {
				return new X509Certificate[]{};
			}
			@Override
			public void checkClientTrusted(X509Certificate[] chain, String authType) {
			}
			@Override
			public void checkServerTrusted(X509Certificate[] chain, String authType) {
			}
		}};
		// Install the all-trusting trust manager
		try {
			SSLContext sc = SSLContext.getInstance("SSL");
			sc.init(null, trustAllCerts, new java.security.SecureRandom());
			HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
